#ifndef WINDOWCONTROL_H
#define WINDOWCONTROL_H

#include <QObject>
#include <QRubberBand>
#include <QStyleOptionFocusRect>
#include <QStylePainter>

class RubberBand;
class CursorPosCalculator;

/**
 * 窗口控制类
 * 存储界面对应的数据集合，及是否可移动、可缩放属性
 * 进行缩放等相关操作
 */
class WindowControl : public QObject {
    Q_OBJECT

  public:
    explicit WindowControl(QObject *parent = nullptr);
    ~WindowControl();
    void activeWindow(QWidget *window);         // 激活窗体
    void removeWindow(QWidget *window);         // 移除窗口
    void setWindowMove(bool moveAble);          // 窗体移动
    void setWindowResize(bool resizeAble);      // 窗体缩放
    void setRubberBandOnMove(bool movable);     // 设置橡皮筋移动
    void setRubberBandOnResize(bool resizable); // 设置橡皮筋缩放

    void handleWidgetEvent(QEvent *event); // 处理鼠标划过、按下、按下、释放、移动事件
    void updateRubberBandStatus();         // 更新橡皮筋状态

  protected:
    virtual bool eventFilter(QObject *obj, QEvent *event); // 事件过滤， 移动，缩放

  private:
    /** 状态 **/
    // QHash<QWidget*, WindowData*> windowDataHash;    // 缓存要控制的窗口
    bool windowMoveAble;           // 可以移动
    bool windowResizeAble;         // 可以缩放
    bool windowRubberBandOnResize; // 可以橡皮筋移动
    bool windowRubberBandOnMove;   // 可以橡皮筋缩放

    /** 窗口及其操作 **/
    RubberBand *m_pRubberBand; // 橡皮筋选择框
    QWidget *m_pWidget;        // 被控制的窗口
    QPoint m_ptDragPos;        // 拖动时坐标
    CursorPosCalculator *m_pressedMousePos;
    CursorPosCalculator *m_moveMousePos;
    bool m_bLeftButtonPressed;      // 鼠标左键是否按下
    bool m_bCursorShapeChanged;     // 鼠标形状是否改变
    bool m_bLeftButtonTitlePressed; // 标题区域是否按下鼠标
    Qt::WindowFlags m_windowFlags;

    void updateCursorShape(const QPoint &gMousePos);  // 更新鼠标样式
    void resizeWidget(const QPoint &gMousePos);       // 重置窗体大小
    void moveWidget(const QPoint &gMousePos);         // 移动窗体
    void handleMousePressEvent(QMouseEvent *event);   // 处理鼠标按下
    void handleMouseReleaseEvent(QMouseEvent *event); // 处理鼠标释放
    void handleMouseMoveEvent(QMouseEvent *event);    // 处理鼠标移动
    void handleLeaveEvent(QEvent *event);             // 处理鼠标离开
    void handleHoverMoveEvent(QHoverEvent *event);    // 处理鼠标进入
};

// ================================================================
/**
 * 窗口控制，
 */
class WindowData {};

// ==================================================================
/**
 * 自定义的橡皮筋选择框
 * @brief The RubberBand class
 */
class RubberBand : public QRubberBand {
  public:
    RubberBand(Shape s, QWidget *p = nullptr) : QRubberBand(s, p) {
        QPalette palette;
        palette.setBrush(QPalette::WindowText, QBrush(Qt::lightGray));
        setPalette(palette); // 调色板应用到当前的橡皮筋对象上
        repaint();
    }

  protected:
    virtual void paintEvent(QPaintEvent *) {
        QStylePainter painter(this);
        QStyleOptionFocusRect option;
        option.initFrom(this);

        QPen pen;
        pen.setStyle(Qt::DashLine);
        pen.setWidth(1);
        pen.setColor(QColor(Qt::red));
        painter.setPen(pen);
        painter.drawControl(QStyle::CE_FocusFrame, option);
    }
};

// ==================================================================
/**
 * 计算鼠标是否位于左、上、右、下、左上角、左下角、右上角、右下角
 */

class CursorPosCalculator {
  public:
    explicit CursorPosCalculator();
    void reset();
    void recalculate(const QPoint &globalMousePos, const QRect &frameRect);

  public:
    bool m_bOnEdges;
    bool m_bOnLeftEdge;
    bool m_bOnRightEdge;
    bool m_bOnTopEdge;
    bool m_bOnBottomEdge;
    bool m_bOnTopLeftEdge;
    bool m_bOnBottomLeftEdge;
    bool m_bOnTopRightEdge;
    bool m_bOnBottomRightEdge;

    static int m_nBorderWidth;    // 边框宽度
    static int m_nTitleHeight;    // 标题栏高度
};

#endif // WINDOWCONTROL_H
